package com.klikmee.sms.cef;

import java.net.URL;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;

import javax.xml.ws.BindingProvider;

import org.apache.log4j.Logger;

import com.klikmee.sms.cef.bulk.BulkSender;
import com.klikmee.sms.cef.core.ws.BulkPayload;
import com.klikmee.sms.cef.core.ws.CoreInterface;
import com.klikmee.sms.cef.core.ws.CoreInterfaceService;
import com.klikmee.sms.cef.core.ws.ServicePayload;

public class CoreAdapter implements BulkSender<Integer> {
	/**
	 * Logger instance
	 */
	private static Logger logger = Logger.getLogger(CoreAdapter.class);
	/**
	 * URL of the WSDL file for the core web service
	 */
	private URL wsdlLocation;
	/**
	 * Stub for the core web service
	 */
	private CoreInterface coreInterface;
	/**
	 * Location of the core web service exposed for service communication
	 */
	private String coreEndpointURL;

	/**
	 * Initializes core adapter, creates web service client and overrides end
	 * point URL
	 */
	public void init() {
		// create core ws client
		coreInterface = new CoreInterfaceService(wsdlLocation).getCoreInterfacePort();
		logger.info("Core adapter initialized");
		// override end point address
		((BindingProvider) coreInterface).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, coreEndpointURL);

		logger.info(String.format("Core adapter initialized, core URL = [%s]", coreEndpointURL));
	}

	/**
	 * Sends response message for the customer's request.
	 * 
	 * @param chargingId
	 *            id of the charging category assigned to the service by core
	 *            platform
	 * @param serviceId
	 *            id of the service assigned by the core platform
	 * @param contentFlag
	 *            flag for this response message. Designates bad or regular
	 *            semantics
	 * @param referenceId
	 *            core id of the message this is the response to
	 * @param messageText
	 *            text of the response
	 * @return core id of the response message. used for status reports.
	 */
	public Long sendMessage(Long chargingId, Long serviceId, int contentFlag, Long referenceId, String messageText) {
		// build service payload
		ServicePayload servicePayload = new ServicePayload();
		servicePayload.setContentFlag(contentFlag);
		servicePayload.setCoreReferenceId(referenceId);
		servicePayload.setText(messageText);
		logger.debug( MessageFormat.format( "Sending message with serviceId = [{0}], chargingId = [{1}], text = [{2}]", serviceId, chargingId, messageText ) );

		return coreInterface.sendMessage(servicePayload, serviceId, chargingId);
	}

	/**
	 * Sends bulk message to the customer.
	 * 
	 * @param chargingId
	 *            core id of the charging used for bulk message
	 * @param serviceId
	 *            core id of the service sending bulk message
	 * @param receivers
	 *            list of receivers of the bulk message
	 * @param messageText
	 *            text of the bulk message
	 * @param signatureText
	 *            signature or the sender id of the bulk message
	 * @return
	 */
	public int sendBulkMessage(Long chargingId, Long serviceId, Collection<? extends String> receivers, String messageText, String signatureText) {
		BulkPayload bulkPayload = new BulkPayload();
		bulkPayload.getReceivers().addAll(receivers);
		bulkPayload.setText(messageText);
		bulkPayload.setSignatureText(signatureText);

		return coreInterface.sendBulkMessage(bulkPayload, serviceId, chargingId);
	}

	public void setCoreEndpointURL(String coreEndPointURL) {
		this.coreEndpointURL = coreEndPointURL;

	}

	public void setWsdlLocation(URL wsdlLocation) {
		this.wsdlLocation = wsdlLocation;
	}

	/**
	 * Sends bulk message over core platform by calling
	 * {@link #sendBulkMessage(Long, Long, Collection, String, String)}
	 * 
	 * @param params
	 *            bulk message parameters
	 */
	@Override
	public Integer send(Hashtable<BulkParams, Object> params) {
		// extract bulk params
		List<String> receivers = (List<String>) params.get(BulkParams.RECEIVERS);
		String senderId = (String) params.get(BulkParams.SENDER);
		String messageText = (String) params.get(BulkParams.TEXT);
		Long coreChargingId = (Long) params.get(BulkParams.CORE_CHARGING_ID);
		Long coreServiceId = (Long) params.get( BulkParams.CORE_SERVICE_ID );
		
		// sent the message
		int sendBulkMessage = this.sendBulkMessage(coreChargingId, coreServiceId, receivers, messageText, senderId);
		return sendBulkMessage;

	}

}
